package app.services;

import app.constant.CommonStatusMap;
import app.constant.OrderConstant;
import app.constant.ProductConstant;
import app.kit.TypeKit;
import app.models.order.AccountAmount;
import app.models.order.Order;
import app.models.order.TradeMoney;
import app.models.product.Product;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import goja.StringPool;
import goja.date.DateFormatter;
import goja.kits.base.DateKit;
import goja.plugins.sqlinxml.SqlKit;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

import static app.Const.FIELD_AMOUNT;
import static app.constant.OrderConstant.TRADE_FAILURE;
import static app.models.order.TradeMoney.DUE_TYPE;
import static app.models.order.TradeMoney.PAY_FAIL_TYPE;
import static goja.StringPool.EMPTY;

/**
 * <p> </p>
 *
 * @author sogYF
 * @version 1.0
 * @since JDK 1.6
 */
public final class ExportService {

    public static final String EXPORT_USER = "export_user";
    public static final String EXPORT_TIME = "export_time";
    public static final String ITEM        = "item";
    public static final String IDX         = "idx";
    public static final String CCN         = "合计";

    private ExportService() {
    }

    public static final ExportService me = new ExportService();


    /**
     * 到处募集失败的数据
     *
     * @param productId 产品ID
     * @param loginName 登录人
     * @param beans     导出数据
     */
    public void invokeFail(int productId, String loginName, Map<String, Object> beans) {


        List<Record> records = Db.find(SqlKit.sql("clearing.productfail.export"), ProductConstant.FAIL, productId, TradeMoney.FAIL_TYPE);
        for (int i = 0; i < records.size(); i++) {
            Record record = records.get(i);
            record.set(IDX, i + 1);
            Number adjust_mode = record.getNumber("adjust_mode");
            BigDecimal amount = record.getBigDecimal(FIELD_AMOUNT);
            if (adjust_mode == null) {
                record.set("back_amount", amount);
            } else {
                BigDecimal adjust_amount = record.getBigDecimal("adjust_amount");
                if (adjust_amount != null) {

                    if (adjust_mode.intValue() == 1) {
                        record.set("back_amount", amount.add(adjust_amount));
                    } else {
                        record.set("back_amount", amount.subtract(adjust_amount));
                    }
                } else {
                    record.set("back_amount", amount);
                }
            }
            Timestamp field_val = record.getTimestamp("buy_time");
            if (field_val == null) {
                record.set("time", EMPTY);
            } else {
                record.set("time", new DateTime(field_val.getTime()).toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS));
            }

            //状态
            String status_name = CommonStatusMap.getChineseTrademoneyStatus(record.getNumber("status").intValue());
            record.set("status_name",status_name);
            //调账方式
            String adjust_mode_name = CommonStatusMap.getAdjustMode(record.getNumber("adjust_mode").intValue());
            //调整金额
            double adjust_amount = record.getNumber("adjust_amount").doubleValue();
            record.set("adjust_amount_name",adjust_mode_name+adjust_amount);

        }

        Product product = Product.dao.findById(productId);
        beans.put(ITEM, records);
        beans.put("product", product);
        DateTime now = DateTime.now();
        beans.put("back_time", now.toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD));
        beans.put("trades", records.size());
        beans.put(EXPORT_TIME, now.toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM));
        beans.put(EXPORT_USER, loginName);
    }

    /**
     * 导出具体产品的转让失败数据
     *
     * @param productId 产品ID
     * @param loginName 登录人
     * @param beans     导出对象
     */
    public void invokeTranser(int productId, String loginName, Map<String, Object> beans) {

        List<Record> records = Db.find(SqlKit.sql("clearing.transfer.export"), productId);
        BigDecimal sumAmount = BigDecimal.ZERO;
        BigDecimal sumPrice = BigDecimal.ZERO;
        for (int i = 0; i < records.size(); i++) {
            Record record = records.get(i);
            record.set(IDX, i + 1);

            sumAmount = sumAmount.add(record.getBigDecimal(FIELD_AMOUNT));
            sumPrice = sumPrice.add(record.getBigDecimal("price"));

            //打款状态
            String status_name = CommonStatusMap.getChineseTrademoneyStatus(record.getNumber("status").intValue());
            record.set("status_name",status_name);
            //调账方式
            String adjust_mode_name = CommonStatusMap.getAdjustMode(record.getNumber("adjust_mode").intValue());
            //调整金额
            double adjust_amount = record.getNumber("adjust_amount").doubleValue();
            record.set("adjust_amount_name",adjust_mode_name+adjust_amount);
            if (record.getNumber("order_status").intValue()==7) {
                record.set("remark", "系统错误钱没转给卖方");
            }else{
                record.set("remark", StringPool.EMPTY);
            }

        }
        Record sumRecord = new Record();
        sumRecord.set(IDX, CCN);
        sumRecord.set("name", EMPTY);
        sumRecord.set("trade_no", EMPTY);
        sumRecord.set("account", EMPTY);
        sumRecord.set("phone", EMPTY);
        sumRecord.set("amount", sumAmount.toPlainString());
        sumRecord.set("price", sumPrice.toPlainString());
        sumRecord.set("fee", EMPTY);
        sumRecord.set("remark", EMPTY);
        sumRecord.set("lodging_fee", EMPTY);
        records.add(sumRecord);

        beans.put(ITEM, records);
        beans.put(EXPORT_TIME, DateTime.now().toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM));
        beans.put(EXPORT_USER, loginName);
    }

    /**
     * 募集成功导出
     *
     * @param productId 产品ID
     * @param loginName 登录人
     * @param beans     导出对象
     */
    public void invokeRaisedSuccess(int productId, String loginName, Map<String, Object> beans) {


        List<Record> records = Db.find(SqlKit.sql("clearing.productlist.export"), productId, OrderConstant.BUY_TYPE);

        for (int i = 0; i < records.size(); i++) {
            Record record = records.get(i);
            record.set(IDX, i + 1);
        }

        Product product = Product.dao.findById(productId);
        beans.put(ITEM, records);
        beans.put("product", product);
        beans.put("trades", Order.dao.statByTypeAndProduct(productId, OrderConstant.BUY_TYPE, OrderConstant.TRADE_SUCCESS));
        DateTime now = DateTime.now();
        String day = now.toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM);
        beans.put(EXPORT_TIME, day);
        beans.put("time", now.toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD));
        beans.put(EXPORT_USER, loginName);
    }

    /**
     * 导出指定的退单信息
     *
     * @param productId 产品ID
     * @param loginName 登录人
     * @param whereSql  SQL语句
     * @param beans     导出对象
     */
    public void invokeCancel(int productId, String loginName, StringBuilder whereSql, Map<String, Object> beans) {
        DateTime now = DateTime.now().millisOfDay().withMaximumValue();
        DateTime start = now.plusWeeks(-2).millisOfDay().withMinimumValue();

        String wher_sql = String.format(SqlKit.sql("clearing.cancel.export"), whereSql.toString());
        List<Record> records = Db.find(wher_sql, TradeMoney.CANCEL_TYPE, start, now);

        BigDecimal sumAmount = BigDecimal.ZERO;
        for (Record record : records) {
            sumAmount = sumAmount.add(record.getBigDecimal(FIELD_AMOUNT));

            //状态
            String status_name = CommonStatusMap.getChineseTrademoneyStatus(record.getNumber("status").intValue());
            record.set("status_name",status_name);
            //调账方式
            String adjust_mode_name = CommonStatusMap.getAdjustMode(record.getNumber("adjust_mode").intValue());
            //调整金额
            double adjust_amount = record.getNumber("adjust_amount").doubleValue();
            record.set("adjust_amount_name",adjust_mode_name+adjust_amount);

        }
        Record sumRecord = new Record();
        sumRecord.set("id", CCN);
        sumRecord.set("name", EMPTY);
        sumRecord.set("tradeno", EMPTY);
        sumRecord.set("phone", EMPTY);
        sumRecord.set("account", EMPTY);
        sumRecord.set("amount", sumAmount.toPlainString());
        sumRecord.set("time", EMPTY);
        records.add(sumRecord);

        beans.put(ITEM, records);
        beans.put(EXPORT_TIME, DateTime.now().toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM));
        beans.put(EXPORT_USER, loginName);
    }

    /**
     * 导出某个产品的到期发放收益。
     *
     * @param productId 产品ID
     * @param loginName 登录人
     * @param whereSql  SQL语句
     * @param params    SQL参数
     * @param beans     导出对象
     */
    public void invokeDue(int productId, String loginName, List<Object> params, StringBuilder whereSql, Map<String, Object> beans) {

        params.add(productId);
        whereSql.append(" AND p.status = ?");
        params.add(ProductConstant.END);


        String wher_sql = String.format(SqlKit.sql("clearing.due.export"), whereSql.toString());
        List<Record> records = Db.find(wher_sql, params.toArray());

        BigDecimal sumAmount = BigDecimal.ZERO;
        BigDecimal sumPrincipal = BigDecimal.ZERO;
        BigDecimal sumProfit = BigDecimal.ZERO;
        for (int i = 0; i < records.size(); i++) {
            Record record = records.get(i);
            record.set(IDX, i + 1);
            sumAmount = sumAmount.add(record.getBigDecimal(FIELD_AMOUNT));
            sumPrincipal = sumPrincipal.add(record.getBigDecimal("principal"));
            sumProfit = sumProfit.add(record.getBigDecimal("profit"));

            //状态
            String status_name = CommonStatusMap.getChineseTrademoneyStatus(record.getNumber("status").intValue());
            record.set("status_name",status_name);
            //调账方式
            String adjust_mode_name = CommonStatusMap.getAdjustMode(record.getNumber("adjust_mode").intValue());
            //调整金额
            double adjust_amount = record.getNumber("adjust_amount").doubleValue();
            record.set("adjust_amount_name",adjust_mode_name+adjust_amount);
        }
        Record sumRecord = new Record();
        sumRecord.set(IDX, CCN);
        sumRecord.set("name", EMPTY);
        sumRecord.set("tradeno", EMPTY);
        sumRecord.set("real_name", EMPTY);
        sumRecord.set("principal", sumPrincipal.toPlainString());
        sumRecord.set("profit", sumProfit.toPlainString());
        sumRecord.set("amount", sumAmount.toPlainString());
        records.add(sumRecord);

        Product product = Product.dao.findByClearing(DUE_TYPE, productId);
        beans.put(ITEM, records);
        beans.put("product", product);
        beans.put(EXPORT_TIME, DateTime.now().toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM));
        beans.put(EXPORT_USER, loginName);
    }

    /**
     * 导出日交易失败结算清单
     *
     * @param day       日期 yyyy-mm-dd
     * @param loginName 登录人
     * @param beans     导出对象
     */
    public void invokePayFail(String day, String loginName, Map<String, Object> beans) {
        DateTime daily = DateKit.parseDashYMDDateTime(day);
        AccountAmount accountAmount = AccountAmount.dao.findByDate(daily);
        BigDecimal balance = TypeKit.getBigdecimal(accountAmount, "balance");
        beans.put("account_amount", balance.toPlainString());
        BigDecimal trade_amount = Order.dao.statByTrade(daily);
        beans.put("trade_amount", trade_amount.toPlainString());

        DateTime start = daily.millisOfDay().withMinimumValue();
        DateTime end = daily.millisOfDay().withMaximumValue();
        List<Record> records = Db.find(SqlKit.sql("clearing.payfail.export"), PAY_FAIL_TYPE, start, end);
        for (int i = 0; i < records.size(); i++) {
            Record record = records.get(i);
            record.set(IDX, i + 1);


            record.set("type", CommonStatusMap.getChineseOrderType(record.getStr("order_type")));
            record.set("status", "账户已收，交易失败" );
            Timestamp field_val = record.getTimestamp("buy_time");
            if (field_val == null) {
                record.set("time", EMPTY);
            } else {
                record.set("time", new DateTime(field_val.getTime()).toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS));
            }
        }
        beans.put(ITEM, records);
        beans.put("day", day);
        beans.put(EXPORT_USER, loginName);
        beans.put(EXPORT_TIME, DateTime.now().toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM));
    }
}
